package com.itheima.esdemo;

import org.apache.http.HttpHost;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.List;

//ES测试类
@SpringBootTest
public class ElasticSearchAggsTest {

    //客户端对象
    private RestHighLevelClient client;

    /**
     * 桶聚合分组查询
     * @throws Exception
     */
    @Test
    public void testAggsTest() throws Exception{

        // 1.创建SearchRequest对象，并制定索引库名称
        SearchRequest searchRequest = new SearchRequest("car");

        //2.创建SearchSourceBuilder对象，设置分组相关参数
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.aggregation(
                AggregationBuilders
                        .terms("popular_color")
                        .field("color.keyword"));
        // 分页参数
        sourceBuilder.size(0);

        // 3.添加SearchSourceBuilder对象到SearchRequest对象source中
        searchRequest.source(sourceBuilder);
        // 4.执行查询
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 5.得到查询结果
        SearchHits responseHits = response.getHits();
        TotalHits totalHits = responseHits.getTotalHits();
        System.out.println("total："+totalHits.value);

        // 6.解析分组查询数据
        Terms terms = (Terms) response.getAggregations().asMap().get("popular_color");
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println(bucket.getKey()+" : "+ bucket.getDocCount());
        }
    }


    /**
     * 桶聚合分组查询
     * @throws Exception
     */
    @Test
    public void testAggsAvgTest() throws Exception{

        // 1.创建SearchRequest对象，并制定索引库名称
        SearchRequest searchRequest = new SearchRequest("car");

        //2.创建SearchSourceBuilder对象，设置分组相关参数
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // ***设置分组参数
        TermsAggregationBuilder popularColorAggs = AggregationBuilders.terms("popular_color").field("color.keyword");

        // ***分组后平均价格计算
        AvgAggregationBuilder priceAggs = AggregationBuilders.avg("avg_price").field("price");
        // ***按颜色分组后添加到子聚合计算
        popularColorAggs.subAggregation(priceAggs);

        sourceBuilder.aggregation(popularColorAggs);
        // 分页参数
        sourceBuilder.size(0);

        // 3.添加SearchSourceBuilder对象到SearchRequest对象source中
        searchRequest.source(sourceBuilder);
        // 4.执行查询
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        // 5.得到查询结果
        SearchHits responseHits = response.getHits();
        TotalHits totalHits = responseHits.getTotalHits();
        System.out.println("total："+totalHits.value);


        // 6.解析分组查询数据
        Terms terms = (Terms) response.getAggregations().asMap().get("popular_color");
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            // ***解析分组数据
            System.out.println(bucket.getKey()+" : "+ bucket.getDocCount());

            // ***解析平均价格
            ParsedAvg parsedAvg = (ParsedAvg) bucket.getAggregations().getAsMap().get("avg_price");
            System.out.println(bucket.getKey()+" 平均价格：" + parsedAvg.getValue());
        }
    }


    /**
     * 建立连接
     */
    @BeforeEach
    public void init() throws IOException {
        //创建Rest客户端
        client = new RestHighLevelClient(
                RestClient.builder(
                        //如果是集群，则设置多个主机，注意端口是http协议的端口
                        new HttpHost("192.168.200.150", 9200, "http")
                )
        );
    }

    /**
     * 关闭客户端连接
     */
    @AfterEach
    public void close() throws IOException {
        client.close();
    }
}